package com.zksk.admin.service.customer.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.cglib.CglibUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksk.admin.domain.agreement.vo.AgreementVo;
import com.zksk.admin.domain.customer.vo.CustomerProdReqFVo;
import com.zksk.admin.domain.customer.vo.CustomerProdReqVo;
import com.zksk.admin.domain.org.dto.SignDto;
import com.zksk.admin.mapper.customer.RAgreementCustomerReqDao;
import com.zksk.admin.mapper.customer.RRateCustomerReqDao;
import com.zksk.admin.mapper.product.ProductReleaseDao;
import com.zksk.admin.service.customer.CustomerProdReqService;
import com.zksk.common.core.domain.R;
import com.zksk.common.security.utils.SecurityUtils;
import com.zksk.mbg.admin.domain.*;
import com.zksk.mbg.admin.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: xiebo
 * @create: 2022-12-02 16:53
 **/
@Service
public class CustomerProdReqServiceImpl extends ServiceImpl<CustomerProdReqMapper, CustomerProdReq> implements CustomerProdReqService
{
    @Autowired
    private CustomerProdReqMapper customerProdReqMapper;

    @Autowired
    private RateMapper rateMapper;

    @Autowired
    private AgreementMapper agreementMapper;

    @Autowired
    private RAgreementCustomerReqDao rAgreementCustomerReqDao;

    @Autowired
    private RRateCustomerReqDao rRateCustomerReqDao;

    @Autowired
    private ProductReleaseDao productReleaseDao;

    /**
     * 根据Id查询产品需求信息
     *
     * @param id
     * @return
     */
    @Override
    public R<CustomerProdReqVo> selectById(Long id)
    {

        CustomerProdReqVo customerProdReqVo = BeanUtil.copyProperties(customerProdReqMapper.selectById(id), CustomerProdReqVo.class);

        //查询协议
        List<Agreement> agreements = rAgreementCustomerReqDao.selectAgreementList(id);
        //将签章信息设置为返回json类型
        List<AgreementVo> collect = agreements.stream()
                .map(item ->
                {
                    AgreementVo agreementVo = BeanUtil.copyProperties(item, AgreementVo.class);
                    if (StrUtil.isNotEmpty(item.getSignInfo()))
                    {
                        List<SignDto> signDtos = JSONObject.parseArray(item.getSignInfo(), SignDto.class);
                        agreementVo.setSignDtos(signDtos);
                    }
                    return agreementVo;
                })
                .collect(Collectors.toList());

        customerProdReqVo
                //查询费率
                .setRateList(rRateCustomerReqDao.selectRateList(id))
                //设置协议
                .setAgreementVos(collect)
                //TODO 支付方式暂时返回固定值
                .setPaymentList(Arrays.asList("支付宝", "微信"));

        return R.ok(customerProdReqVo);
    }

    /**
     * 分页查询
     *
     * @param customerProdReqFVo
     * @return
     */
    @Override
    public R<Page<CustomerProdReqVo>> selectList(CustomerProdReqFVo customerProdReqFVo)
    {

        Page<CustomerProdReqVo> voPage = new Page<>();
        Page<CustomerProdReq> customerProdReqPage = customerProdReqMapper.selectPage
                (
                        //分页
                        new Page<>(customerProdReqFVo.getPageNum(), customerProdReqFVo.getPageSize()),
                        //条件构造
                        new LambdaQueryWrapper<CustomerProdReq>()
                                .eq(CustomerProdReq::getCustomerId, customerProdReqFVo.getCustomerId())
                                .eq(CustomerProdReq::getDelFlag, 0)
                );
        //实体转Vo
        BeanUtil.copyProperties(customerProdReqPage, voPage);
        return R.ok(voPage);
    }

    @Override
    public CustomerProdReq selectCustomerId(Long id) {
        return null;
    }


    /**
     * 新增客户产品需求
     *
     * @param customerProdReqVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public R insert(CustomerProdReqVo customerProdReqVo)
    {

        //如果传了ID设置为Null,主要针对swagger测试时忘了删除ID
        customerProdReqVo.setId(null);

        //客户产品需求新增
        CustomerProdReq customerProdReq = BeanUtil.copyProperties(customerProdReqVo, CustomerProdReq.class);

        customerProdReq
                .setDelFlag(0)//设置删除标识为存在
                .setCreateBy(SecurityUtils.getUsername()); //设置创建人

        customerProdReqMapper.insert(customerProdReq);

        //新增费率和协议以及其中间表 绑定支付方式
        this.insertRateAndAgreement(
                customerProdReqVo.getRateList(),
                customerProdReqVo.getAgreementVos(),
                customerProdReq.getId()
        );

        return R.ok(customerProdReq.getId(), "插入成功!");
    }

    /**
     * 新增费率、协议、以及中间关系表
     *
     * @param rateList
     * @param agreementVos
     * @param id
     */
    private void insertRateAndAgreement(List<Rate> rateList, List<AgreementVo> agreementVos, Long id)
    {
        //客户费率新增
        rateList.forEach(rate ->
        {
            rate
                    //如果传了ID设置为Null,主要针对swagger测试时忘了删除ID
                    .setId(null)
                    //设置创建人
                    .setCreateBy(SecurityUtils.getUsername());

            //新增费率表
            rateMapper.insert(rate);
            //绑定费率和产品需求
            rRateCustomerReqDao.insert(
                    RRateCustomerReq
                            .builder()
                            .rateId(rate.getId())
                            .customerProdReqId(id)
                            .build()
            );
        });

        //客户协议新增
        agreementVos.forEach(agreementVo ->
        {
            Agreement agreement = BeanUtil.copyProperties(agreementVo, Agreement.class);

            agreement
                    // 如果传了ID设置为Null,主要针对swagger测试时忘了删除ID
                    .setId(null)
                    // 设置创建人
                    .setCreateBy(SecurityUtils.getUsername());
            // 新增协议签章位置
            List<SignDto> signDtos = agreementVo.getSignDtos();

            if (CollUtil.isNotEmpty(signDtos))
            {
                // 插入协议的签章位置
                agreement.setSignInfo(JSONObject.toJSONString(signDtos));
            }
            //新增协议表
            agreementMapper.insert(agreement);
            //绑定协议和产品需求
            rAgreementCustomerReqDao.insert(
                    RAgreementCustomerReq
                            .builder()
                            .agreementId(agreement.getId())
                            .customerProdReqId(id)
                            .build()
            );
        });

        //绑定支付方式
        //TODO
    }

    /**
     * 删除费率、协议、以及中间关系表
     *
     * @param ids 客户产品需求集合
     */
    private void deleteRateAndAgreement(List<Long> ids)
    {

        //协议条件
        LambdaQueryWrapper<RAgreementCustomerReq> rAgreementWrapper = new LambdaQueryWrapper<RAgreementCustomerReq>()
                .in(RAgreementCustomerReq::getCustomerProdReqId, ids);

        //删除协议表数据
        List<Long> rAIds = rAgreementCustomerReqDao
                //查询关系表数据
                .selectList(rAgreementWrapper)
                .stream()
                //取出协议表ID
                .map(RAgreementCustomerReq::getAgreementId)
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(rAIds))
        {
            agreementMapper.deleteBatchIds(rAIds);
        }

        //删除产品协议和客户产品需求关系表数据
        rAgreementCustomerReqDao.delete(rAgreementWrapper);

        //费率条件
        LambdaQueryWrapper<RRateCustomerReq> rRateWrapper = new LambdaQueryWrapper<RRateCustomerReq>()
                .in(RRateCustomerReq::getCustomerProdReqId, ids);

        //删除费率表数据
        List<Long> rRIds = rRateCustomerReqDao
                //查询关系表数据
                .selectList(rRateWrapper)
                .stream()
                //取出费率表ID
                .map(RRateCustomerReq::getRateId)
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(rRIds))
        {
            rateMapper.deleteBatchIds(rRIds);
        }

        //删除费率和客户产品需求关系表
        rRateCustomerReqDao.delete(rRateWrapper);

        //删除支付方式绑定
        //TODO

    }


    /**
     * 批量删除客户产品需求
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deletes(List<Long> ids)
    {
        //删除费率和协议以及其中间表
        this.deleteRateAndAgreement(ids);
        return R.ok("删除" + customerProdReqMapper.deleteBatchIds(ids) + "条数据!", "删除成功!");
    }

    /**
     * 修改客户产品需求
     *
     * @param customerProdReqVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateCustomerProdReq(CustomerProdReqVo customerProdReqVo)
    {
        //删除费率和协议以及其中间表
        this.deleteRateAndAgreement(Arrays.asList(customerProdReqVo.getId()));

        //新增费率和协议以及其中间表
        this.insertRateAndAgreement(
                customerProdReqVo.getRateList(),
                customerProdReqVo.getAgreementVos(),
                customerProdReqVo.getId()
        );

        CustomerProdReq customerProdReq = BeanUtil.copyProperties(customerProdReqVo, CustomerProdReq.class);

        //设置修改人
        customerProdReq.setUpdateBy(SecurityUtils.getUsername());

        int i = customerProdReqMapper.updateById(customerProdReq);

        return R.ok("修改了" + i + "条数据!", "修改成功!");
    }

}
